#include "F1TDC.hh"

const unsigned int F1TDC::F1_SLOT_ID_MASK              = 0xf8000000;
const unsigned int F1TDC::F1_RESOLUTION_LOCKED_MASK    = 0x04000000;
const unsigned int F1TDC::F1_OUTPUT_FIFO_OVERFLOW_MASK = 0x02000000;
const unsigned int F1TDC::F1_HIT_FIFO_OVERFLOW_MASK    = 0x01000000;
const unsigned int F1TDC::F1_DATA_TYPE_MASK            = 0x00800000;
const unsigned int F1TDC::F1_DATA_MASK                 = 0x0000ffff;
const unsigned int F1TDC::F1_CHANNEL_NUMBER_MASK       = 0x003f0000;

const unsigned int F1TDC::F1_HT_TRIG_FIFO_MASK         = 0x00400000;
const unsigned int F1TDC::F1_HT_EVENT_NUMBER_MASK      = 0x003f0000;
const unsigned int F1TDC::F1_HT_TRIG_TIME_MASK         = 0x0000ff80;
const unsigned int F1TDC::F1_HT_XOR_SETUP_REG_MASK     = 0x00000040;
const unsigned int F1TDC::F1_HT_CHANNEL_NUMBER_MASK    = 0x0000003f;

F1TDC::F1TDC()
{ 
  slot_id                      = 0;
  resolution_locked            = 0; 
  output_fifo_overflow         = 0;
  hit_fifo_overflow            = 0;

  data_type                    = 0;    
  data                         = 0;
  channel_number               = 0;

  header_trigger_fifo_overflow = 0;
  header_event_number          = 0;
  header_trigger_time          = 0;
  header_xor_setup_reg         = 0;
  header_channel_number        = 0;

  return_decoded_data.clear();
  decoded_stream.clear();
  valid_slot_flag              = false;
};

F1TDC::F1TDC(const char *char_wrd)
{ 
  Decode( char_wrd );
  
};



F1TDC::~F1TDC() { };


void F1TDC::Decode(const char *char_wrd)
{
  unsigned long int wrd =  strtoul (char_wrd, NULL, 16);

  if(wrd != 0) {
    slot_id              = BitMaskShift(wrd, F1_SLOT_ID_MASK,              27);
    resolution_locked    = BitMaskShift(wrd, F1_RESOLUTION_LOCKED_MASK,    26);
    output_fifo_overflow = BitMaskShift(wrd, F1_OUTPUT_FIFO_OVERFLOW_MASK, 25);
    hit_fifo_overflow    = BitMaskShift(wrd, F1_HIT_FIFO_OVERFLOW_MASK,    24);

    decoded_stream << "----------------------------------------- \n";
    decoded_stream << "       F1TDC at Slot " << slot_id <<"\n";
    decoded_stream << "----------------------------------------- \n";
    decoded_stream << "  Input HEX number          : " << char_wrd << "\n";
    decoded_stream << "  Chip Resolution Locked    : " << resolution_locked    << "\n";
    decoded_stream << "  Chip Output FIFO Overflow : " << output_fifo_overflow << "\n";
    decoded_stream << "  Chip Hit    FIFO overflow : " << hit_fifo_overflow    << "\n";

    data_type            = BitMaskShift(wrd, F1_DATA_TYPE_MASK,            23);

    if(data_type == 1) {
      // data word
      channel_number       = BitMaskShift(wrd, F1_CHANNEL_NUMBER_MASK,       16);
      data                 = BitMaskShift(wrd, F1_DATA_MASK,                  0);
      decoded_stream << "  Data Word  \n";
      decoded_stream << "  -- Channel  : " << channel_number << "\n";
      decoded_stream << "  -- Data     : " << data << "\n";
    }
    else {
      
      // header & trailer word
      header_trigger_fifo_overflow = BitMaskShift(wrd, F1_HT_TRIG_FIFO_MASK,     22);
      header_event_number          = BitMaskShift(wrd, F1_HT_EVENT_NUMBER_MASK,  16);
      header_trigger_time          = BitMaskShift(wrd, F1_HT_TRIG_FIFO_MASK,      7);
      header_xor_setup_reg         = BitMaskShift(wrd, F1_HT_XOR_SETUP_REG_MASK,  6);
      header_channel_number        = BitMaskShift(wrd, F1_HT_CHANNEL_NUMBER_MASK, 0);
      decoded_stream << "  Header/Trailer Word  \n";
      decoded_stream << "  -- Trigger FIFO Overflow  : " << header_trigger_fifo_overflow << "\n";
      decoded_stream << "  -- Event Number           : " << header_event_number          << "\n";
      decoded_stream << "  -- Xor Setup Register     : " << header_xor_setup_reg         << "\n";
      decoded_stream << "  -- Channel Number         : " << header_channel_number        << "\n";
      decoded_stream << "  -- Trigger Time           : " << header_trigger_time          << "\n";
    }
    
    if( slot_id>=1 && slot_id<=21 ) valid_slot_flag = true;
    else                            valid_slot_flag = false;
    
    data_input_flag = true;
    
  }
  else {
    decoded_stream << "No HEX number is the input Entry" << std::endl;
    data_input_flag = false;
  }
  decoded_stream << std::endl;
  return_decoded_data = decoded_stream.str();
  
  return;
};


void F1TDC::PrintHeader()
{
  if(data_input_flag) {
    printf(">>>>>>>>> H/T  : Ch %2d, Xor %1d, trOvF %1d, Chip(hitOvF,outOvF,resLock)(%1d%1d%1d) SlotID %2d Event # %d Trig Time %d\n",
	   header_channel_number, header_xor_setup_reg,  header_trigger_fifo_overflow,
	   hit_fifo_overflow, output_fifo_overflow, resolution_locked,
	   slot_id, header_event_number, header_trigger_time);
  }
  else {
    printf("no HEX number is the input Entry\n");
  }
  return;
};


void F1TDC::PrintData()
{
  if(data_input_flag) {
    printf(">>>>>>>>> DATA : Ch ");
    printf("%2d", channel_number);
    printf("%18s", "");
    printf("Chip(hitOvF,outOvF,resLock)(%1d%1d%1d) SlotID %2d",
	   hit_fifo_overflow, output_fifo_overflow, resolution_locked, slot_id);
    printf(", Raw time");
    printf("%12d\n", data);
  }
  else {
    printf("no HEX number is the input Entry\n");
  }
  return;
};




